import numpy as np
from itertools import combinations
from datetime import datetime
from mpi4py import MPI
import pymysql
from tensorflow import keras
from keras import regularizers

import sys
import copy

sys.path.append('../../')

from craft_all_five import bone, x1one, x2one,x3one, x4one, x5one, x6one, x7one, x8one, x9one, x10one, x11one, x12one, y1one, y2one, y3one, y4one, y5one

from splitglo import *
from neuralnet.shareglob import *

# OK here
#resisparse0=[]
#resisparsecb=[]

class cotblend(object):
#   def __init__(self):

#   def cottonblending(self, new_rank, size, nsplit, color,rank,comm):
   def cottonblending(self):

      # OK here
      resisparse0=[]
      resisparsecb=[]

      def cv(a):
         cvout=np.std(a, ddof)/np.mean(a)
         return cvout
      
      def cvariation(a):
         cvtest=False
         cv=np.std(a, ddof)/np.mean(a)
#         if (cv< 0.05):
         if (cv< 0.8):
           cvtest=True
         return cvtest

      def multilayer_network():
      
          model=keras.models.Sequential()
          model.add(keras.layers.Dense(input_shape=(n_input,), units=n_hidden1, kernel_regularizer=regularizers.l2(eta), activation='sigmoid'))
      #    model.add(keras.layers.Dense(n_hidden1, activation='sigmoid'))
          model.add(keras.layers.Dense(n_hidden2, kernel_regularizer=regularizers.l2(eta), activation='sigmoid'))
          model.add(keras.layers.Dense(n_hidden3, kernel_regularizer=regularizers.l2(eta), activation='sigmoid'))
          model.add(keras.layers.Dense(n_hidden4, kernel_regularizer=regularizers.l2(eta), activation='sigmoid'))
          model.add(keras.layers.Dense(n_hidden5, kernel_regularizer=regularizers.l2(eta), activation='sigmoid'))
          model.add(keras.layers.Dense(n_hidden6, kernel_regularizer=regularizers.l2(eta), activation='sigmoid'))
          model.add(keras.layers.Dense(n_output, activation=None))
      
          return model

      def trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data):
            cottonftry0=np.zeros(n_input)
#            cottonftry1=[]
           
#            model=multilayer_network()
#            model.load_weights('weights-biases-all-keras.hdf5')
         
            if (new_rank==numper):#for k in range(n_input):
             if (residual !=0):
              if (it < residual):#for k in range(n_input):
                 for k in range(n_input):
                     for i in range(ncb):
                         cottonftry0[k] += np.array(coefftmp[i]*combdeach[it][i][2][k])
#                     cottonftry1.append(cottonftry0)
                 cottonftry00=np.array([cottonftry0,cottonftry0])
                 predout0=model.predict(cottonftry00)
                 errtmp=(np.linalg.norm(predout0[0][:] - predict_data[:]))/np.linalg.norm(predict_data[:])
                 if errtmp<10.3:
                    resisparse0.append(errtmp)
                    resisparsecb.append(coefftmp)

             else:
                 for k in range(n_input):
                     for i in range(ncb):
                         cottonftry0[k] += np.array(coefftmp[i]*combdeach[it][i][2][k])
#                     cottonftry1.append(cottonftry0)
           
                 cottonftry00=np.array([cottonftry0,cottonftry0])
                 predout0=model.predict(cottonftry00)
                 errtmp=(np.linalg.norm(predout0[0][:] - predict_data[:]))/np.linalg.norm(predict_data[:])
                 if errtmp<10.3:
                    resisparse0.append(errtmp)
                    resisparsecb.append(coefftmp)
    
            else:
                 for k in range(n_input):
                     for i in range(ncb):
                         cottonftry0[k] += np.array(coefftmp[i]*combdeach[it][i][2][k])
#                     cottonftry1.append(cottonftry0)
           
                 cottonftry00=np.array([cottonftry0,cottonftry0])
                 predout0=model.predict(cottonftry00)
                 errtmp=(np.linalg.norm(predout0[0][:] - predict_data[:]))/np.linalg.norm(predict_data[:])
                 if errtmp<10.3:
                    resisparse0.append(errtmp)
                    resisparsecb.append(coefftmp)
          
#            return resisparse0, resisparsecb


      def datamysql():
         filters=[]

         # 打开数据库连接
         db = pymysql.connect("172.16.34.71", "root", "HUAyuan123456!!!", "icdsdata")
         
         # 使用cursor()方法获取操作游标
         cursor = db.cursor()
         
         # SQL 查询语句
         sql = """
         SELECT
         `peimian_2019_distinct`.`公司内部批号`,
         `peimian_2019_distinct`.`产地`,
         `peimian_2019_distinct`.`马克隆值`,
         `peimian_2019_distinct`.`平均长度`,
         `peimian_2019_distinct`.`断裂比强度`,
         `peimian_2019_distinct`.`回潮率`,
         `peimian_2019_distinct`.`含杂率`,
         `peimian_2019_distinct`.`可纺系数`,
         `peimian_2019_distinct`.`成熟度`,
         `peimian_2019_distinct`.`整齐度`,
         `peimian_2019_distinct`.`短纤指数`,
         `peimian_2019_distinct`.`反射率`,
         `peimian_2019_distinct`.`黄度`,
         `peimian_2019_distinct`.`棉结`
         
         FROM
         `peimian_2019_distinct`
         """
         
         try:
             # 执行SQL语句
             cursor.execute(sql)
             # 获取所有记录列表
             resultsori = cursor.fetchall()
             # print(resultsori)
#             cottonalltest=[row for row in resultsori]
             cottonall=[row for row in resultsori]
        
                 # 打印结果
#             print('data = ', len(cottonalltest))
#             print('data = ', cottonalltest[0:10])
         except Exception as e:
             print("Error: unable to fetch data",e)
         
         # 关闭数据库连接
         db.close()
         if (rank==0):
            print('cottonall= ', cottonall[:][:][0])
            print('len(cottonall)= ', len(cottonall))
            print('len(cottonall[0])= ', len(cottonall[0]))

         craftnum=2
         dimcottx=len(cottonall[0])
         if (rank==0):
            print('if dimcottx + 1 is equal to n_input + 2 ?', dimcottx +1 ==n_input +2 )
         dimcott=len(cottonall)

         cottonnum=[]
#         cottonnum=np.zeros((len(cottonall),len(cottonall[0])-2 +1,craftnum))
#         cottonnor=np.zeros((len(cottonall),len(cottonall[0])-2 +1,craftnum))
         cottonnew=np.zeros(( dimcott, dimcottx -2+1,craftnum))
         cottonnor=np.zeros(( dimcott, dimcottx -2+1,craftnum))

         for i in range(dimcott):
            for j in range(dimcottx-2):
              for k in range(craftnum):
                cottonnew[i][j][k]=np.array(eval(cottonall[i][j+2]))
#                cottonnew[i][j][1]=np.array(eval(cottonall[i][j+2]))
            cottonnew[i][dimcottx-2][0]=np.array(0.1)
            cottonnew[i][dimcottx-2][1]=np.array(0.5)
    
         if (rank==0):
            print('len(cottonnew) = ', len(cottonnew))
            print('len(cottonnew) = ', len(cottonnew[0]))
            print('len(cottonnew) = ', len(cottonnew[0][0]))

         for k in range(craftnum):
          cottoncraft=[]
          for i in range(dimcott):
            cottonpart=[]
#    is np.array() necessary?
            cottonpart.append(cottonall[i][0])
            cottonpart.append(cottonall[i][1])
#            cottonpart.append(np.array(cottonall[i][0]))
#            cottonpart.append(np.array(cottonall[i][1]))
            cottonpart.append(cottonnew[i,:,k])

            cottoncraft.append(cottonpart)
#          if (rank==0):
#             print('cottoncraft dim = ', len(cottoncraft))
#             print('cottoncraft shape = ', np.array(cottoncraft[0][2]).shape)

          cottonnum.append(cottoncraft)

         if (rank==0):
            print('cottonnum dim = ', len(cottonnum))
#            print('cottonnum dim = ', len(cottonnum[0]))
#            print('cottonnum dim = ', len(cottonnum[0][0]))
#            print('cottonnum dim = ', len(cottonnum[0][0][0]))
            print('cottonnum= ', cottonnum[0][:][2])

         cottonori=[ a for a in (bone, x1one, x2one, x3one, x4one, x5one, x6one, x7one, x8one, x9one, x10one, x11one, x12one, y1one, y2one, y3one, y4one, y5one)]

         for k in range(craftnum):
          for i in range(dimcott):
           for j in range(n_input):
             cottonnor[i,j,k]=(cottonnum[k][i][2][j] - min(cottonori[j]) - 0.02)/(max(cottonori[j])- min(cottonori[j])+ 0.05)

         if (rank==0):
            print('cottonnor dim = ', len(cottonnor))
            print('cottonnor shape = ', np.array(cottonnor).shape)

#         speciesnum=13
         speciesnum=12
#         speciesnum=16
         for k in range(speciesnum):
#            filters.append(cottonnum[0][k][:][:])
            filters.append(cottonnum[0][k])

         if (rank==0):
            print('len(filters)= ', len(filters))
#            print('len(filters)= ', len(filters[0][0][2]))
    
         combd=[]
         ncb=10
#         ncb=13
#         ncb=15
         if(ncb<10 and ncb>20):
            print('Cotton species should be in the range of 10-20')
            exit()

#         ncb=num
         for combina in combinations(filters,ncb):
          combd.append(combina)
         
         if (rank==0):
            print('len(combd)= ',len(combd))
#            print('len(combd)= ',len(combd[0]))
#            print('len(combd)= ',len(combd[0][0]))
#            print('len(combd)= ',len(combd[0][0][2]))

         return combd, ncb, craftnum
     
# all possible discrete number 
      combd, ncb, craftnum=datamysql()
#      ndiscrete=2
      ndiscrete=4
      ncott=ncb
      ndisall=ndiscrete**(ncott-1)
      
      # discrete step
      xx = np.zeros((ncb, ndiscrete))
     
      cottonkpi=np.zeros((n_input, craftnum)) 
#      resisparseall=[]
      costall=[]
#      resisparseallcb=[]
      resivalue=[]
    
#      responsetextile = requests.get('http://127.0.0.1:8000/textilelist')#,
#  #                             auth=('username', 'password'))
#      textiledata = responsetextile.json()
#      print('data= ',len(textiledata['results']))# = response.json()
#      textiletest=[[a['textilestr'], a['textilen']] for a in textiledata['results']]
#      print('textiletest = ',textiletest[0])
#      textilelist=[eval(a) for a in textiletest[0] ]
#      print('textilelist = ',textilelist)

      textilelist=np.array([40., 16., 87., 335., 98.])
      npred=len(textilelist)#predresu=[]
      predict_data=textilelist
      yall=[]
      for a in (y1one, y2one, y3one, y4one, y5one):
        yall.append(a)
      for i in range(npred):
        predict_data[i]=(predict_data[i]-min(yall[i])+0.005)/(max(yall[i])-min(yall[i])+0.01)	# yarn strength

      if (rank==0):
         print('predict textile original= ', predict_data)

 
      model=multilayer_network()

#      print('textilenum= ', textilenum)
      if (textilenum >= 9. and textilenum <= 11.):
          model.load_weights('/home/hy/icds_new/weights-biases-out5-10.hdf5')
      elif (textilenum > 11. and textilenum <= 15.):
          model.load_weights('/home/hy/icds_new/weights-biases-out5-10-15.hdf5')
      elif (textilenum > 15. and textilenum <= 19.5):
          model.load_weights('/home/hy/icds_new/weights-biases-out5-15-20.hdf5')
      elif (textilenum > 19.5 and textilenum <= 24.):
          model.load_weights('/home/hy/icds_new/weights-biases-out5-20-24.hdf5')
      elif (textilenum > 24. and textilenum <= 29.5):
          model.load_weights('/home/hy/icds_new/weights-biases-out5-25-30.hdf5')
      elif (textilenum > 29.5 and textilenum <= 35.):
          model.load_weights('/home/hy/icds_new/weights-biases-out5-30-35.hdf5')
      elif (textilenum > 35. and textilenum <= 40.5):
          model.load_weights('/home/hy/icds_new/weights-biases-out5-35-40.hdf5')
      #         model.load_weights('/home/hy/icds_new/info/modules/api/weights-biases-all-keras.hdf5')
      elif (textilenum > 40. and textilenum <= 59.5):
          model.load_weights('/home/hy/icds_new/weights-biases-out5-40.hdf5')

#      model.load_weights('weights-biases-all-keras.hdf5')
        
#      combd=datamysql()
      trange=len(combd)
      remainder=trange % (size/nsplit)
     
      addyes=False 
#      addyes=True 
      if(addyes==True and remainder!=0):
#         mpin=int(trange/size) +1
         mpin=int(trange/(size/nsplit)) +1

         appendco=mpin*(size/nsplit) - trange
#         numper=int(trange/mpin)

         combdsup=copy.deepcopy(combd[:appendco])   # deepcopy or reference

         if (remainder >0) :# and residual !=0:

            if (rank==0):
               print('trange = ', trange)
               print('remainder = ', remainder)
               print('appendco = ', appendco)
               print('len(combdsup)= ', len(combdsup))
#               print('combd addition= ', combdsup[0])

            for k in range(appendco):
             for i in range(ncb):
               for j in range(n_input):
                  combdsup[k][i][2][j]=10.0
        
            if(addyes==True):
               for i in range(appendco):
                  combd.append(combdsup[i])

            if (rank==0):
#               print('combd addition= ', combdsup[0])
               print('combd addition= ', len(combdsup))

      elif (addyes== False and remainder==0):
#         mpin=int(trange/size)
         mpin=int(trange/(size/nsplit))
         numper=int(trange/mpin)
         residual=trange%mpin

      elif (addyes== False and remainder!=0):
#         mpin=int(trange/size)+1
         mpin=int(trange/(size/nsplit))+1
         residual=trange%mpin
         numper=int(trange/mpin)

      if (rank==0):
         print('len(combd) new= ', len(combd))
#         print('combd new= ', combd)

#      if (len(combd)!= (trange + appendco)):
#          exit()

      combdeach=[]
      resisparseeach=[]
      resisparseeachcb=[]

      if(addyes==True and remainder!=0):
         for it in range(mpin):
          combdeach.append(combd[it + new_rank*mpin])

      elif (addyes== False and remainder==0):
         for it in range(mpin):
          combdeach.append(combd[it + new_rank*mpin])

      elif (addyes== False and remainder!=0):
       if(residual !=0):
        if(new_rank< numper):
         for it in range(mpin):
         #for it in range(trange):
          combdeach.append(combd[it + new_rank*mpin])
   
        if(new_rank== numper):
         for it in range(residual):
             combdeach.append(combd[it+ numper*mpin])

       else:
        if(new_rank< numper):
         for it in range(mpin):
         #for it in range(trange):
          combdeach.append(combd[it + new_rank*mpin])
   
#      print('len(combdeach)= ', len(combdeach), rank )#for it in range(mpin):

#      if (addyes== False and remainder!=0):
      if (len(combdeach)>0):#for it in range(mpin):
         for it in range(mpin):

          resisparseall=[]
          resisparseallcb=[]

          if (rank==0): 
             print('test number= ',it)

#          print('combd 4 index = ', np.array(combd)[it,:,4,0])
#          print('combd 0 index = ', np.array(combd)[it,:,0,0])
         
          if (new_rank==numper):#for k in range(n_input):
           if (residual !=0):
            if (it < residual):#for k in range(n_input):
               for k in range(n_input):
                  cottontmp=[]
                  for i in range(ncb):
#                      cottontmp.append(combd[it][i][2][k])
                      cottontmp.append(combdeach[it][i][2][k])
                  cottonkpi[k][0]=cvariation(np.array(cottontmp))
                  cottonkpi[k][1]=cvariation(np.array(cottontmp))

           else:
               for k in range(n_input):
                  cottontmp=[]
                  for i in range(ncb):
#                      cottontmp.append(combd[it][i][2][k])
                      cottontmp.append(combdeach[it][i][2][k])
                  cottonkpi[k][0]=cvariation(np.array(cottontmp))
                  cottonkpi[k][1]=cvariation(np.array(cottontmp))

          else:
               for k in range(n_input):
                  cottontmp=[]
                  for i in range(ncb):
#                      cottontmp.append(combd[it][i][2][k])
                      cottontmp.append(combdeach[it][i][2][k])
                  cottonkpi[k][0]=cvariation(np.array(cottontmp))
                  cottonkpi[k][1]=cvariation(np.array(cottontmp))

# here is local variable, need return to get value
#          resisparse0=[]
#          resisparsecb=[]
          coeff=[]
          cost=[]
          
#          print('coefficient of variation: ', cv(uhl), cv(bte), cv(mic))
#          print('is all true? ', (cottonkpi == True).all())
          if ((cottonkpi == True).all()): 

#           mpin=int(ndiscrete/(size/nsplit))
           submpi=int(ndiscrete/nsplit)
         
           delta=1./ndiscrete/4.
           startd=1./ndiscrete/4.
           if(ncb>13):#startd=1./ndiscrete/4.
              startd=1./20.
              delta =1./20.

           if(ncb>17):#startd=1./ndiscrete/4.
              startd=1./25.
              delta =1./25.

           sumtmax=1. - startd
           sumtmin=startd*ncb

#           for i1 in range(mpin):
#            x1[i1]=startd + delta*(new_rank*mpin + i1)
#            for i2 in range(submpi):
#             x2[i2]=startd + delta*(color*submpi + i2)
           for i1 in range(submpi):
            xx[0][i1]=startd + delta*(color*submpi + i1)
            for i2 in range(ndiscrete):
             xx[1][i2]=startd + delta*i2
             for i3 in range(ndiscrete):
              xx[2][i3]=startd + delta*i3
              for i4 in range(ndiscrete):
               xx[3][i4]=startd + delta*i4
               for i5 in range(ndiscrete):
                xx[4][i5]=startd + delta*i5
                for i6 in range(ndiscrete):
                 xx[5][i6]=startd + delta*i6
                 for i7 in range(ndiscrete):
                  xx[6][i7]=startd + delta*i7
                  for i8 in range(ndiscrete):
                    xx[7][i8]=startd + delta*i8
#                    if(ncb>9):
                    for i9 in range(ndiscrete):
                       xx[8][i9]=startd + delta*i9
                       if(ncb==10):
                          sumt=xx[0][i1]+xx[1][i2] +xx[2][i3] +xx[3][i4] + xx[4][i5] + xx[5][i6] + xx[6][i7] + xx[7][i8] + xx[8][i9]
  
                          if((sumt < sumtmax) and (sumt > sumtmin)):
                            xxpart=1.- sumt
                            coefftmp=np.array([xx[0][i1],xx[1][i2],xx[2][i3],xx[3][i4],xx[4][i5],xx[5][i6],xx[6][i7],xx[7][i8],xx[8][i9],xxpart])
                
                            trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data)

                       if(ncb>10):
                        for i10 in range(ndiscrete):
                          xx[9][i10]=startd + delta*i10
                          if(ncb==11):
                             sumt=xx[0][i1]+xx[1][i2] +xx[2][i3] +xx[3][i4] + xx[4][i5] + xx[5][i6] + xx[6][i7] + xx[7][i8] + xx[8][i9] + xx[9][i10]
    
                             if((sumt < sumtmax) and (sumt > sumtmin)):
                               xxpart=1.- sumt
                               coefftmp=np.array([xx[0][i1],xx[1][i2],xx[2][i3],xx[3][i4],xx[4][i5],xx[5][i6],xx[6][i7],xx[7][i8],xx[8][i9],xx[9][i10],xxpart])
                    
                               trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data)

                          if(ncb>11):
                           for i11 in range(ndiscrete):
                             xx[10][i11]=startd + delta*i11
                             if(ncb==12):
                                sumt=xx[0][i1]+xx[1][i2] +xx[2][i3] +xx[3][i4] + xx[4][i5] + xx[5][i6] + xx[6][i7] + xx[7][i8] + xx[8][i9] + xx[9][i10] + xx[10][i11]
    
                                if((sumt < sumtmax) and (sumt > sumtmin)):
                                  xxpart=1.- sumt
                                  coefftmp=np.array([xx[0][i1],xx[1][i2],xx[2][i3],xx[3][i4],xx[4][i5],xx[5][i6],xx[6][i7],xx[7][i8],xx[8][i9],xx[9][i10],xx[10][i11],xxpart])
                    
                                  trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data)

                             if(ncb>12):
                              for i12 in range(ndiscrete):
                                xx[11][i12]=startd + delta*i12
                                if(ncb==13):
                                   sumt=xx[0][i1]+xx[1][i2] +xx[2][i3] +xx[3][i4] + xx[4][i5] + xx[5][i6] + xx[6][i7] + xx[7][i8] + xx[8][i9] + xx[9][i10] + xx[10][i11] + xx[11][i12]

                                   if((sumt < sumtmax) and (sumt > sumtmin)):
                                     xxpart=1.- sumt
                                     coefftmp=np.array([xx[0][i1],xx[1][i2],xx[2][i3],xx[3][i4],xx[4][i5],xx[5][i6],xx[6][i7],xx[7][i8],xx[8][i9],xx[9][i10],xx[10][i11],xx[11][i12],xxpart])

                                     trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data)

                                if(ncb>13):
                                 for i13 in range(ndiscrete):
                                   xx[12][i13]=startd + delta*i13
                                   if(ncb==14):
                                      sumt=xx[0][i1]+xx[1][i2] +xx[2][i3] +xx[3][i4] + xx[4][i5] + xx[5][i6] + xx[6][i7] + xx[7][i8] + xx[8][i9] + xx[9][i10] + xx[10][i11] + xx[11][i12] + xx[12][i13]

                                      if((sumt < sumtmax) and (sumt > sumtmin)):
                                        xxpart=1.- sumt
                                        coefftmp=np.array([xx[0][i1],xx[1][i2],xx[2][i3],xx[3][i4],xx[4][i5],xx[5][i6],xx[6][i7],xx[7][i8],xx[8][i9],xx[9][i10],xx[10][i11],xx[11][i12],xx[12][i13],xxpart])
                 

                                        trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data)

                                   if(ncb>14):
                                    for i14 in range(ndiscrete):
                                      xx[13][i14]=startd + delta*i14
                                      if(ncb==15):
                                         sumt=xx[0][i1]+xx[1][i2] +xx[2][i3] +xx[3][i4] + xx[4][i5] + xx[5][i6] + xx[6][i7] + xx[7][i8] + xx[8][i9] + xx[9][i10] + xx[10][i11] + xx[11][i12] + xx[12][i13] + xx[13][i14]

                                         if((sumt < sumtmax) and (sumt > sumtmin)):
                                           xxpart=1.- sumt
                                           coefftmp=np.array([xx[0][i1],xx[1][i2],xx[2][i3],xx[3][i4],xx[4][i5],xx[5][i6],xx[6][i7],xx[7][i8],xx[8][i9],xx[9][i10],xx[10][i11],xx[11][i12],xx[12][i13],xx[13][i14],xxpart])
                 
                                           trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data)

                                      if(ncb>15):
                                       for i15 in range(ndiscrete):
                                         xx[14][i15]=startd + delta*i15
                                         if(ncb==16):
                                            sumt=xx[0][i1]+xx[1][i2] +xx[2][i3] +xx[3][i4] + xx[4][i5] + xx[5][i6] + xx[6][i7] + xx[7][i8] + xx[8][i9] + xx[9][i10] + xx[10][i11] + xx[11][i12] + xx[12][i13] + xx[13][i14] + xx[14][i15]

                                            if((sumt < sumtmax) and (sumt > sumtmin)):
                                              xxpart=1.- sumt
                                              coefftmp=np.array([xx[0][i1],xx[1][i2],xx[2][i3],xx[3][i4],xx[4][i5],xx[5][i6],xx[6][i7],xx[7][i8],xx[8][i9],xx[9][i10],xx[10][i11],xx[11][i12],xx[12][i13],xx[13][i14],xx[14][i15],xxpart])
                 
                                              trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data)

                                         if(ncb>16):
                                          for i16 in range(ndiscrete):
                                            xx[15][i16]=startd + delta*i16
                                            if(ncb==17):
                                               sumt=xx[0][i1]+xx[1][i2] +xx[2][i3] +xx[3][i4] + xx[4][i5] + xx[5][i6] + xx[6][i7] + xx[7][i8] + xx[8][i9] + xx[9][i10] + xx[10][i11] + xx[11][i12] + xx[12][i13] + xx[13][i14] + xx[14][i15] + xx[15][i16]

                                               if((sumt < sumtmax) and (sumt > sumtmin)):
                                                 xxpart=1.- sumt
                                                 coefftmp=np.array([xx[0][i1],xx[1][i2],xx[2][i3],xx[3][i4],xx[4][i5],xx[5][i6],xx[6][i7],xx[7][i8],xx[8][i9],xx[9][i10],xx[10][i11],xx[11][i12],xx[12][i13],xx[13][i14],xx[14][i15],xx[15][i16],xxpart])
                 
                                                 trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data)

                                            if(ncb>17):
                                             for i17 in range(ndiscrete):
                                               xx[16][i17]=startd + delta*i17
                                               if(ncb==18):
                                                  sumt=xx[0][i1]+xx[1][i2] +xx[2][i3] +xx[3][i4] + xx[4][i5] + xx[5][i6] + xx[6][i7] + xx[7][i8] + xx[8][i9] + xx[9][i10] + xx[10][i11] + xx[11][i12] + xx[12][i13] + xx[13][i14] + xx[14][i15] + xx[15][i16] + xx[16][i17]

                                                  if((sumt < sumtmax) and (sumt > sumtmin)):
                                                    xxpart=1.- sumt
                                                    coefftmp=np.array([xx[0][i1],xx[1][i2],xx[2][i3],xx[3][i4],xx[4][i5],xx[5][i6],xx[6][i7],xx[7][i8],xx[8][i9],xx[9][i10],xx[10][i11],xx[11][i12],xx[12][i13],xx[13][i14],xx[14][i15],xx[15][i16],xx[16][i17],xxpart])
                 
                                                    trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data)

                                               if(ncb>18):
                                                for i18 in range(ndiscrete):
                                                  xx[17][i18]=startd + delta*i18
                                                  if(ncb==19):
                                                     sumt=xx[0][i1]+xx[1][i2] +xx[2][i3] +xx[3][i4] + xx[4][i5] + xx[5][i6] + xx[6][i7] + xx[7][i8] + xx[8][i9] + xx[9][i10] + xx[10][i11] + xx[11][i12] + xx[12][i13] + xx[13][i14] + xx[14][i15] + xx[15][i16] + xx[16][i17] + xx[17][i18]

                                                     if((sumt < sumtmax) and (sumt > sumtmin)):
                                                       xxpart=1.- sumt
                                                       coefftmp=np.array([xx[0][i1],xx[1][i2],xx[2][i3],xx[3][i4],xx[4][i5],xx[5][i6],xx[6][i7],xx[7][i8],xx[8][i9],xx[9][i10],xx[10][i11],xx[11][i12],xx[12][i13],xx[13][i14],xx[14][i15],xx[15][i16],xx[16][i17],xx[17][i18],xxpart])

                                                       trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data)

                                                  if(ncb>19):
                                                   for i19 in range(ndiscrete):
                                                     xx[18][i19]=startd + delta*i19
                                                     if(ncb==20):
                                                        sumt=xx[0][i1]+xx[1][i2] +xx[2][i3] +xx[3][i4] + xx[4][i5] + xx[5][i6] + xx[6][i7] + xx[7][i8] + xx[8][i9] + xx[9][i10] + xx[10][i11] + xx[11][i12] + xx[12][i13] + xx[13][i14] + xx[14][i15] + xx[15][i16] + xx[16][i17] + xx[17][i18] + xx[18][i19]

                                                        if((sumt < sumtmax) and (sumt > sumtmin)):
                                                          xxpart=1.- sumt
                                                          coefftmp=np.array([xx[0][i1],xx[1][i2],xx[2][i3],xx[3][i4],xx[4][i5],xx[5][i6],xx[6][i7],xx[7][i8],xx[8][i9],xx[9][i10],xx[10][i11],xx[11][i12],xx[12][i13],xx[13][i14],xx[14][i15],xx[15][i16],xx[16][i17],xx[17][i18],xx[18][i19],xxpart])

                                                          trycomb(new_rank, n_input, numper, residual, ncb, it, coefftmp, combdeach, predict_data)

          
          if (new_rank==numper):#for k in range(n_input):
           if (residual !=0):
            if (it < residual):#for k in range(n_input):
               if (len(resisparse0)>0):
                  resisparsemin=min(resisparse0)
                  indextmpmin=np.where(resisparse0==min(resisparse0))
          
                  cbmintmp=resisparsecb[indextmpmin[0][0]]
                 
               resisparseeach.append(resisparsemin)
               resisparseeachcb.append(cbmintmp)

           else:
               if (len(resisparse0)>0):
                  resisparsemin=min(resisparse0)
                  indextmpmin=np.where(resisparse0==min(resisparse0))
          
                  cbmintmp=resisparsecb[indextmpmin[0][0]]
                 
               resisparseeach.append(resisparsemin)
               resisparseeachcb.append(cbmintmp)
         
          else:
               resisparsemin=[]
               cbmintmp=[]
               if (len(resisparse0)>0):
                  resisparsemin=min(resisparse0)
                  indextmpmin=np.where(resisparse0==min(resisparse0))
          
                  cbmintmp=resisparsecb[indextmpmin[0][0]]
                 
               resisparseeach.append(resisparsemin)
               resisparseeachcb.append(cbmintmp)
         
#          print('len(resisparseeach)= ', len(resisparseeach))#.append(resisparsemin)

      sendbuf=np.array(resisparseeach).reshape(-1)
      sendcounts=np.array(comm.gather(len(sendbuf), root))
     
      sendbufcoe=np.array(resisparseeachcb).reshape(-1)
      sendcountscoe=np.array(comm.gather(len(sendbufcoe), root))

#      sendbufrank=np.array([rank]).reshape(-1)
      sendbufrank=np.array(new_rank).reshape(-1)
      sendcountsrank=np.array(comm.gather(len(sendbufrank), root))

      send_data = new_rank                                                    
#      print "process {} send data {} to root...".format(rank, send_data)  
      recv_data = comm.gather(send_data, root=0)

# sendcounts only works in root process
      if rank==0:
         print('sendrecv counts 1= ',sendcounts, new_rank, it)
         print('sendrecv counts 2= ',sendcountscoe, new_rank, it)
#         print('sendrecv counts 3= ',recv_data, rank, it)
     
     # resisparse_gather=None
      if rank==0:
         recvbuf=np.empty(sum(sendcounts), dtype='d' )
         recvbufcoe=np.empty(sum(sendcountscoe), dtype='d' )
#         recvbufrank=np.empty(sum(sendcountsrank), dtype='i' )
      else:
         recvbuf=None
         recvbufcoe=None
#         recvbufrank=None
     
      comm.Gatherv(sendbuf=sendbuf, recvbuf=(recvbuf, sendcounts), root=0)
      comm.Gatherv(sendbuf=sendbufcoe, recvbuf=(recvbufcoe, sendcountscoe), root=0)
#      comm.Gatherv(sendbuf=sendbufrank, recvbuf=(recvbufrank, sendcountsrank), root=0)
     
      if rank==0:
         resisparse_gather=recvbuf
         resisparsecoe_gather=recvbufcoe
#         resisparserank_gather=recvbufrank


      if (rank==0):
        resimin=min(resisparse_gather)
        print('resimin= ',resimin)
        print('resisparse_gather length = ',len(resisparse_gather))
#        print('rank_gather = ',resisparserank_gather)
        indexnmin=np.where(resisparse_gather==min(resisparse_gather))
        print('resimin index= ',indexnmin)
#        print('resimin index= ',indexnmin[0][0])
        numgather=len(resisparse_gather)
        resisparsecoe_gather=[resisparsecoe_gather[ncb*i:(ncb*(i+1))] for i in range(numgather)]
#        print('resisparsecoe_gather = ',resisparsecoe_gather)
        print('resisparsecoe_gather length = ', len(resisparsecoe_gather))

#        print('resisparse_gather= ',resisparse_gather)
#        print('resisparsecoe_gather= ', resisparsecoe_gather)
        amin=resisparsecoe_gather[indexnmin[0][0]]
        print('amin shape= ',np.array(amin).shape)
        print('index of minimum of abs error=',amin)
        #print('valuemin= ', resivalue[0])
##        valuemin=resivalue[indexnmin[0][0]]
##        print('value of cotton = ', valuemin)
        
        cottonpred=np.zeros( n_input)
        for k in range(n_input):
           for i in range(ncb):
              cottonpred[k] += np.array(np.array(amin[i])*combd[indexnmin[0][0]][i][2][k])
   
        print('cottonpred  ', cottonpred[:])
   
   #     for k in range(ncb):
        print('cottonpred ori= ', combd[indexnmin[0][0]][:])
        
#cottbrun=cotblend()
#cottbrun.cottonblending()
